package com.hatic.process;

import java.util.List;
import java.util.Map;

import org.jxstar.control.action.RequestContext;
import org.jxstar.dao.DaoParam;
import org.jxstar.service.BusinessObject;

/**
 * 项目进度计划数据处理类。
 *
 * @author TonyTan
 * @version 1.0, 2011-10-24
 */
public class ProjectPlanBO extends BusinessObject {
	private static final long serialVersionUID = 1L;

	public String savePlan(RequestContext request) {
		String[] keyids = request.getRequestValues("keyid");
		String[] tasks = request.getRequestValues("task_content");
		String[] sdates = request.getRequestValues("done_sdate");
		String[] edates = request.getRequestValues("done_edate");
		String[] days = request.getRequestValues("done_day");
		String[] ratios = request.getRequestValues("done_ratio");
		
		int num = keyids.length;
		if (num != sdates.length || num != edates.length || num != days.length || 
				num != ratios.length || num != tasks.length) {
			setMessage("项目工作实际进度保存参数不正确！");
			return _returnFaild;
		}
		
		for (int i = 0; i < keyids.length; i++) {
			savePlan(keyids[i], tasks[i], sdates[i], edates[i], days[i], ratios[i]);
		}
		
		return _returnSuccess;
	}
	
	private boolean savePlan(String planId, String task, 
			String sdate, String edate, String day, String ratio) {
		String sql = "update project_plan set " +
				"task_content = ?, done_sdate = ?, done_edate = ?, done_day = ?, done_ratio = ? " +
				"where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(task);
		param.addDateValue(sdate);
		param.addDateValue(edate);
		param.addDoubleValue(day);
		param.addDoubleValue(ratio);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	/**
	 * 检查前置任务号、父任务号的正确性；
	 * 控制只能有三级任务，检查每个任务的父任务号最终都为空，不能循环引用
	 * @param taskIds
	 * @return
	 */
	public String checkTaskNo(String[] mplanIds) {
		if (mplanIds == null || mplanIds.length == 0) {
			setMessage("没有选择项目工作计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < mplanIds.length; i++) {
			String ret = checkTaskNo(mplanIds[i]);
			if (ret.equals(_returnFaild)) return _returnFaild;
			
			updateDone(mplanIds[i]);
		}
		
		return _returnSuccess;
	}
	
	//检查项目工作计划明细的任务号的有效性
	public String checkTaskNo(String mplanId) {
		String preNo1 = checkTaskNo1(mplanId, "pre_no");
		if (preNo1.length() > 0) {
			setMessage("【{0}】的前置任务号是无效任务号，不能提交！", preNo1);
			return _returnFaild;
		}
		
		String preNo2 = checkTaskNo2(mplanId, "pre_no");
		if (preNo2.length() > 0) {
			setMessage("【{0}】的前置任务号与自身的任务号相同，不能提交！", preNo2);
			return _returnFaild;
		}
		
		String parentNo1 = checkTaskNo1(mplanId, "parent_no");
		if (parentNo1.length() > 0) {
			setMessage("【{0}】的父任务号是无效任务号，不能提交！", parentNo1);
			return _returnFaild;
		}
		
		String parentNo2 = checkTaskNo2(mplanId, "parent_no");
		if (parentNo2.length() > 0) {
			setMessage("【{0}】的父任务号与自身的任务号相同，不能提交！", parentNo2);
			return _returnFaild;
		}
		
		String checkNo = checkParentNo(mplanId);
		if (checkNo.length() > 0) {
			setMessage("【{0}】的任务超过三级，不能提交！", checkNo);
			return _returnFaild;
		}
		
		return _returnSuccess;
	}
	
	//检查父任务号不能循环引起，控制最多只能有三级任务
	private String checkParentNo(String mplanId) {
		String sql = "select task_no from project_plan where mplan_id = ? and parent_no > ' ' and task_no in " + 
					 "(select parent_no from project_plan where mplan_id = ? and parent_no > ' ' and task_no in " + 
					 "(select parent_no from project_plan where mplan_id = ? and parent_no > ' '))";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mplanId);
		param.addStringValue(mplanId);
		param.addStringValue(mplanId);
		List<Map<String, String>> lsData = _dao.query(param);
		
		if (lsData.isEmpty()) return "";
		
		return getTaskNo(lsData);
	}
	
	//检查前置任务号的正确性：所有前置任务号或父任务号必须是一个有效的任务号
	//pre_no -- 前置任务号字段；parent_no -- 父任务号字段
	private String checkTaskNo1(String mplanId, String fieldName) {
		String sql = "select task_no from project_plan where mplan_id = ? and "+ fieldName +" not in " + 
					 "(select task_no from project_plan where mplan_id = ?)";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mplanId);
		param.addStringValue(mplanId);
		List<Map<String, String>> lsData = _dao.query(param);
		
		if (lsData.isEmpty()) return "";
		
		return getTaskNo(lsData);
	}
	
	//检查前置任务号的正确性：前置任务号或父任务号不能是自己的任务号
	//pre_no -- 前置任务号字段；parent_no -- 父任务号字段
	private String checkTaskNo2(String mplanId, String fieldName) {
		String sql = "select task_no from project_plan where mplan_id = ? and "+ fieldName +" = task_no";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mplanId);
		List<Map<String, String>> lsData = _dao.query(param);
		
		if (lsData.isEmpty()) return "";
		
		return getTaskNo(lsData);
	}
	
	//取无效的任务号
	private String getTaskNo(List<Map<String, String>> lsData) {
		if (lsData.isEmpty()) return "";
		
		StringBuilder sbTaskNo = new StringBuilder();
		for (int i = 0, n = lsData.size(); i < n; i++) {
			sbTaskNo.append(lsData.get(i).get("task_no")).append(";");
		}
		
		return sbTaskNo.substring(0, sbTaskNo.length() - 1);
	}
	
	//更新实际时间值
	private boolean updateDone(String mplanId) {
		String sql = "update project_plan set done_sdate = start_date, " +
				"done_edate = end_date, done_day = project_day where mplan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mplanId);
		
		return _dao.update(param);
	}
}
